﻿namespace CSharPro._1023;
using System.Collections.Generic;
using System.Linq;

// 性别枚举（规范性别取值）
public enum Gender
{
    Male,   // 男
    Female  // 女
}

/// <summary>
/// 学生类，封装学生的基本信息和操作
/// </summary>

public class Student
{
    // 私有字段（封装数据）
    private string _id;         // 学号（唯一标识）
    private string _name;       // 姓名
    private int _age;           // 年龄
    private Gender _gender;     // 性别
    private Dictionary<string, double> _scores;  // 成绩字典（科目-分数）


    // 公共属性（提供访问控制和数据验证）
    /// <summary>
    /// 学号（只读，构造函数初始化）
    /// </summary>
    public string Id 
    { 
        get => _id; 
        private set 
        { 
            if (string.IsNullOrWhiteSpace(value))
                throw new ArgumentException("学号不能为空");
            _id = value; 
        } 
    }

    /// <summary>
    /// 姓名
    /// </summary>
    public string Name 
    { 
        get => _name; 
        set 
        { 
            if (string.IsNullOrWhiteSpace(value))
                throw new ArgumentException("姓名不能为空");
            _name = value; 
        } 
    }

    /// <summary>
    /// 年龄（1-150岁之间）
    /// </summary>
    public int Age 
    { 
        get => _age; 
        set 
        { 
            if (value < 1 || value > 150)
                throw new ArgumentOutOfRangeException("年龄必须在1-150岁之间");
            _age = value; 
        } 
    }

    /// <summary>
    /// 性别
    /// </summary>
    public Gender Gender { get => _gender; set => _gender = value; }

    /// <summary>
    /// 成绩集合（只读，通过方法修改）
    /// </summary>
    public IReadOnlyDictionary<string, double> Scores => _scores.AsReadOnly();


    // 构造函数（初始化对象）
    /// <summary>
    /// 初始化学生信息
    /// </summary>
    /// <param name="id">学号</param>
    /// <param name="name">姓名</param>
    /// <param name="age">年龄</param>
    /// <param name="gender">性别</param>
    public Student(string id, string name, int age, Gender gender)
    {
        Id = id;       // 调用属性的setter（触发验证）
        Name = name;   // 调用属性的setter（触发验证）
        Age = age;     // 调用属性的setter（触发验证）
        Gender = gender;

        // 初始化成绩字典
        _scores = new Dictionary<string, double>();
    }


    // 方法（提供学生相关操作）
    /// <summary>
    /// 添加或更新学生的科目成绩（分数必须在0-100之间）
    /// </summary>
    /// <param name="subject">科目名称</param>
    /// <param name="score">分数</param>
    public void AddOrUpdateScore(string subject, double score)
    {
        if (string.IsNullOrWhiteSpace(subject))
            throw new ArgumentException("科目名称不能为空");
        if (score < 0 || score > 100)
            throw new ArgumentOutOfRangeException("分数必须在0-100之间");

        if (_scores.ContainsKey(subject))
            _scores[subject] = score;  // 更新已有科目成绩
        else
            _scores.Add(subject, score);  // 添加新科目成绩
    }

    /// <summary>
    /// 计算所有科目的平均分
    /// </summary>
    /// <returns>平均分（无成绩时返回0）</returns>
    public double CalculateAverageScore()
    {
        if (_scores.Count == 0)
            return 0;
        return _scores.Values.Average();
    }

    /// <summary>
    /// 显示学生的详细信息
    /// </summary>
    public void DisplayInfo()
    {
        Console.WriteLine($"=== 学生信息 ===");
        Console.WriteLine($"学号：{Id}");
        Console.WriteLine($"姓名：{Name}");
        Console.WriteLine($"年龄：{Age}");
        Console.WriteLine($"性别：{Gender}");
        Console.WriteLine("成绩：");
        if (_scores.Count == 0)
        {
            Console.WriteLine("  暂无成绩");
        }
        else
        {
            foreach (var (subject, score) in _scores)
            {
                Console.WriteLine($"  {subject}：{score}分");
            }
            Console.WriteLine($"  平均分：{CalculateAverageScore():F1}分");
        }
        Console.WriteLine("===============");
    }

    /// <summary>
    /// 重写ToString方法，返回简洁的学生信息
    /// </summary>
    /// <returns>学生信息字符串</returns>
    public override string ToString()
    {
        return $"{Id} - {Name}（{Gender}，{Age}岁）";
    } 
}